#include "MTVariableDefinition.hpp"
#include "MTInteger.hpp"
#include "MTDouble.hpp"
#include "MTFloat.hpp"
#include "MTExpression.hpp"
#include "Params.h"
#include <string>
#include <iostream>
#include <sstream>

namespace MathematicaTranslator
{
	std::string* MTVariableDefinition::generateCode(CodeGenContext& context)
	{
		std::ostringstream ss;
		
		if( context.locals().find(id.name) != context.locals().end()) 
		{
			//variable exist - switch it's value
			 ss << *id.generateCode(context);
			 ss << " = ";
			 ss << *assignExpression->generateCode(context);
			 
			 #ifdef DEBUG
				std::cout<<"Variable definition exists - switching" << *id.generateCode(context) << std::endl;
			#endif
		} else 
		{
			int backup = MTNode::tmpVariableCount;
			std::string *text = assignExpression->generateCode(context) ;
			MTNode::tmpVariableCount = backup;

			std::string *type = assignExpression->getType();
			int k = type->find_first_of("[");
			if (k != -1){
				std::ostringstream v0;
				v0 << MTNode::tmpVariable << MTNode::tmpVariableCount;
				std::string var0 = v0.str(); 

				int k2 = type->find_first_of("]");
				
				std::string underlyingType = type->substr(0,k);
				std::string underlyingTypeSize = type->substr(k, k2 - k + 1);

				ss << underlyingType << " " << var0 << underlyingTypeSize << " = " << "{ 0 }" << ";" << "\n";
				ss << underlyingType << " ";	
				ss << "*" << *id.generateCode(context);
				ss << " = ";
				ss << var0 << ";" << "\n";
				ss << *assignExpression->generateCode(context);
			}
			else {			
				ss << *assignExpression->getType() << " ";
				ss << *id.generateCode(context);
				ss << " = ";
				ss << *text;
			}
			//ss << *assignExpression->generateCode(context) ;		

			#ifdef DEBUG
				std::cout<<"Variable definition created" << *id.generateCode(context) <<std::endl;
			#endif
		}
		std::string* generatedValue = new std::string(ss.str()); 

		//place new/modified value back to locals()
		context.locals()[id.name] = generatedValue;

		return generatedValue;
	}

}
